home *** CD-ROM | disk | FTP | other *** search
/ Windows Expert / Windows Expert.iso / others / ole_101.zip / PATRON.ZIP / OLEDOC.C < prev    next >
C/C++ Source or Header  |  1992-04-13  |  10KB  |  379 lines

  1. /*
  2.  * OLEDOC.C
  3.  *
  4.  * Constructor, Destructor, and utility functions for the DOCUMENT
  5.  * structure that contains document-related OLE information and a
  6.  * pointer to the document's OLESTREAM structure
  7.  *
  8.  * Copyright(c) Microsoft Corp. 1992 All Rights Reserved
  9.  */
  10.  
  11. #include <windows.h>
  12. #include <ole.h>
  13. #include "oclient.h"
  14.  
  15.  
  16. //Array of string pointers, global to OLE-specific code.
  17. char NEAR *rgpszOLE[COLESTRINGS];
  18.  
  19. /*
  20.  * Memory containing the strings and a lock count.  The first time
  21.  * PDocumentAllocate is called, we load the strings and increment the
  22.  * lock.  For each PDocumentFree call we decrement the count.  If it's
  23.  * decremented to zero we free the string memory.
  24.  */
  25.  
  26. WORD        cStringLock=0;
  27. HANDLE      hMemStrings;
  28.  
  29.  
  30.  
  31.  
  32. /*
  33.  * PDocumentAllocate
  34.  *
  35.  * Purpose:
  36.  *  Constructor method for the DOCUMENT data type.  Allocates a DOCUMENT
  37.  *  and sets the defaults in its fields:
  38.  *      Initalize OLECLIENTVTBL and OLESTREAMVTBL
  39.  *      Allocate and initialize an OLESTREAM structure (see OLESTREA.C)
  40.  *      Register OLE clipboard formats
  41.  *      Allocate scratch data and set pointers within it.
  42.  *
  43.  *  Used from application initialization.
  44.  *
  45.  * Parameters:
  46.  *  pfSuccess       LPBOOL indicating if the initialization succeeded.  If
  47.  *                  this function returns non-NULL, but *pfSuccess==FALSE,
  48.  *                  the caller must call the destructor function.
  49.  *  hInst           HANDLE of the application instance.
  50.  *  pszCaption      LPSTR to the application name.
  51.  *  pfnCallBack     FARPROC to the single client method to initialize.
  52.  *                  We pass this function to PVtblClientAllocate.
  53.  *  pfnGet          FARPROC to this document's Stream Get method.
  54.  *  pfnPut          FARPROC to this document's Stream Put method.
  55.  *
  56.  * Return Value:
  57.  *  LPDOCUMENT      Pointer to the allocated DOCUMENT if successful,  NULL
  58.  *                  if the allocation failed or a parameter is invalid.
  59.  */
  60.  
  61. LPDOCUMENT FAR PASCAL PDocumentAllocate(LPBOOL pfSuccess, HANDLE hInst,
  62.                                         LPSTR pszCaption, FARPROC pfnCallBack,
  63.                                         FARPROC pfnGet, FARPROC pfnPut)
  64.     {
  65.     LPDOCUMENT          pDoc;
  66.     HANDLE              hMem;
  67.     BOOL                fTemp;
  68.  
  69.     /*
  70.      * Any error condition will return FALSE unless we get all through
  71.      * this function.  This scheme allows us to always return on any
  72.      * error instead of trying to clean up what was already initialized.
  73.      * Instead, we let the destructor, PDocumentFree, do the work.
  74.      */
  75.  
  76.     if (NULL==pfSuccess)
  77.         return NULL;
  78.  
  79.     *pfSuccess=FALSE;
  80.  
  81.     if (NULL==hInst || NULL==pszCaption)
  82.         return NULL;
  83.  
  84.     //Allocate this structure.
  85.     hMem=LocalAlloc(LPTR, CBDOCUMENT);
  86.  
  87.     if (NULL==hMem)
  88.         return NULL;
  89.  
  90.     pDoc=(LPDOCUMENT)(PSTR)hMem;
  91.  
  92.     /*
  93.      * The first time we allocate a DOCUMENT, load the strings and
  94.      * increment a counter.  On subsequent DOCUMENT allocations, just
  95.      * copy the handle and increment the counter.  The destructor
  96.      * function will decrement the counter and free the memory if
  97.      * the last DOCUMENT is freed.
  98.      */
  99.     if (0==cStringLock)
  100.         {
  101.         hMemStrings=HLoadOLEStrings(hInst);
  102.  
  103.         if (NULL==hMemStrings)
  104.             return pDoc;
  105.         }
  106.  
  107.     cStringLock++;
  108.  
  109.  
  110.     //Save the document name
  111.     pDoc->aCaption=AddAtom(pszCaption);
  112.  
  113.     //1. Register clipboard formats; the strings are globals in this file.
  114.     pDoc->cfNative    =RegisterClipboardFormat(PSZOLE(IDS_NATIVE));
  115.     pDoc->cfOwnerLink =RegisterClipboardFormat(PSZOLE(IDS_OWNERLINK));
  116.     pDoc->cfObjectLink=RegisterClipboardFormat(PSZOLE(IDS_OBJECTLINK));
  117.  
  118.     //Any error, return what we already allocated.
  119.     if (0==pDoc->cfNative || 0==pDoc->cfOwnerLink || 0==pDoc->cfObjectLink)
  120.         return pDoc;
  121.  
  122.  
  123.     //2. Get initialized OLECLIENTVTBL pointer.
  124.     pDoc->pvt=PVtblClientAllocate(&fTemp, hInst, pfnCallBack);
  125.  
  126.     if (!fTemp)
  127.         return pDoc;
  128.  
  129.  
  130.     //3. Get an initialized STREAM pointer.
  131.     pDoc->pStream=PStreamAllocate(&fTemp, hInst, pfnGet, pfnPut);
  132.  
  133.     if (!fTemp)
  134.         return pDoc;
  135.  
  136.  
  137.     //4.  Allocate scratch memory.
  138.     pDoc->hData=GlobalAlloc(GHND, CSCRATCH*CBSCRATCH);
  139.  
  140.     if (NULL==pDoc->hData)
  141.         return pDoc;
  142.  
  143.     /*
  144.      * Initialize global pointers into this memory.  Since we know we
  145.      * allocated with a nonzero byte count, GlobalLock will work.
  146.      */
  147.     pDoc->pszData1=GlobalLock(pDoc->hData);
  148.     pDoc->pszData2=pDoc->pszData1+CBSCRATCH;
  149.     pDoc->pszData3=pDoc->pszData2+CBSCRATCH;
  150.  
  151.  
  152.  
  153.  
  154.     //Everything handled successfully.
  155.     *pfSuccess=TRUE;
  156.     return pDoc;
  157.     }
  158.  
  159.  
  160.  
  161.  
  162. /*
  163.  * PDocumentFree
  164.  *
  165.  * Purpose:
  166.  *  Frees all data in the DOCUMENT and frees the structure.
  167.  *
  168.  * Parameters:
  169.  *  pDoc            LPDOCUMENT to the structure to free.
  170.  *
  171.  * Return Value:
  172.  *  LPDOCUMENT      NULL if the function succeeds, pDoc otherwise.
  173.  */
  174.  
  175. LPDOCUMENT FAR PASCAL PDocumentFree(LPDOCUMENT pDoc)
  176.     {
  177.     BOOL        fRet=FALSE;
  178.  
  179.     /*
  180.      * Free the scratch memory if we have any.  No need to clear the
  181.      * pointers since we'll be freeing this structure anyway.
  182.      */
  183.  
  184.     if (NULL!=pDoc->hData)
  185.         GlobalFree(pDoc->hData);
  186.  
  187.     if (pDoc->aCaption)
  188.         DeleteAtom(pDoc->aCaption);
  189.  
  190.     //Free the stream we're holding
  191.     if (NULL!=PStreamFree(pDoc->pStream))
  192.         return pDoc;
  193.  
  194.     //Free this object's VTBL
  195.     if (NULL!=PVtblClientFree(pDoc->pvt))
  196.         return pDoc;
  197.  
  198.     if (NULL!=LocalFree((HANDLE)(DWORD)pDoc))
  199.         return pDoc;
  200.  
  201.     //Free the strings if this was the only DOCUMENT around.
  202.     if (0==--cStringLock)
  203.         {
  204.         if (NULL!=hMemStrings)
  205.             LocalFree(hMemStrings);
  206.         }
  207.  
  208.     return NULL;
  209.     }
  210.  
  211.  
  212.  
  213. /*
  214.  * FDocumentFileSet
  215.  *
  216.  * Purpose:
  217.  *  Provides the document with an associated filename for use in
  218.  *  OLE-related UI.
  219.  *
  220.  * Parameters:
  221.  *  pDoc            LPDOCUMENT in which to store the filename.
  222.  *  pszFile         LPSTR to the filename of the document.
  223.  *
  224.  * Return Value:
  225.  *  BOOL            TRUE if the function succeeds, FALSE otherwise.
  226.  */
  227.  
  228. BOOL FAR PASCAL FDocumentFileSet(LPDOCUMENT pDoc, LPSTR pszFile)
  229.     {
  230.     if (NULL==pDoc || NULL==pszFile)
  231.         return FALSE;
  232.  
  233.     if (pDoc->aFile)
  234.         DeleteAtom(pDoc->aFile);
  235.  
  236.     pDoc->aFile=AddAtom(pszFile);
  237.     return TRUE;
  238.     }
  239.  
  240.  
  241.  
  242.  
  243.  
  244. /*
  245.  * PDocumentMsgProcSet
  246.  *
  247.  * Purpose:
  248.  *  Informs the DOCUMENT structure about a function in the main application
  249.  *  that translates and dispatches messages.  This prevents the DOCUMENT
  250.  *  from having to carry an accelerator handle or window handle and
  251.  *  allows the application to perform other actions we cannot predict
  252.  *  (like IsDialogMessage).
  253.  *
  254.  * Parameters:
  255.  *  pDoc            LPDOCUMENT to the structure concerned.
  256.  *  pfn             LPFNMSGPROC to the message processing function.
  257.  *
  258.  * Return Value:
  259.  *  None
  260.  */
  261.  
  262. void FAR PASCAL PDocumentMsgProcSet(LPDOCUMENT pDoc, LPFNMSGPROC pfn)
  263.     {
  264.     if (NULL!=pDoc)
  265.         pDoc->pfnMsgProc=pfn;
  266.  
  267.     return;
  268.     }
  269.  
  270.  
  271.  
  272.  
  273. /*
  274.  * PDocumentBackgroundProcSet
  275.  *
  276.  * Purpose:
  277.  *  Informs the DOCUMENT structure about a function in the main application
  278.  *  that performs background operations when there are no messages to
  279.  *  process.  This is necessary to provide a standard release waiting
  280.  *  message loop such that that loop can call the background process
  281.  *  function when it detects idle time.
  282.  *
  283.  * Parameters:
  284.  *  pDoc            LPDOCUMENT to the structure concerned.
  285.  *  pfn             LPFNMSGPROC to the background processing function.
  286.  *
  287.  * Return Value:
  288.  *  None
  289.  */
  290.  
  291. void FAR PASCAL PDocumentBackgroundProcSet(LPDOCUMENT pDoc, LPFNMSGPROC pfn)
  292.     {
  293.     if (NULL!=pDoc)
  294.         pDoc->pfnBackProc=pfn;
  295.  
  296.     return;
  297.     }
  298.  
  299.  
  300.  
  301.  
  302.  
  303.  
  304.  
  305. /*
  306.  * HLoadOLEStrings
  307.  *
  308.  * Purpose:
  309.  *  Allocates FIXED local memory and reads the applications
  310.  *  string resources into that memory.  Each string's pointer
  311.  *  is available through the PSZOLE(i) macro where i is the ID
  312.  *  value of the string.  The strings must have sequential IDs.
  313.  *
  314.  *  Note that string pointers are stored in the rgpszOLE global
  315.  *  array defined in this file.
  316.  *
  317.  * Parameters:
  318.  *  hInst           HANDLE of the application instance.
  319.  *
  320.  * Return Value:
  321.  *  HANDLE          Handle to the local memory.  NULL if memory could
  322.  *                  not be allocated.
  323.  */
  324.  
  325. HANDLE PASCAL HLoadOLEStrings(HANDLE hInst)
  326.     {
  327.     HANDLE      hMem;
  328.     char NEAR   *pch;
  329.     WORD        cchUsed=0;
  330.     WORD        cch;
  331.     short       i;
  332.  
  333.     /*
  334.      * Allocate memory and load strings.  NOTE!  The LPTR style
  335.      * specifies FIXED memory.  This should not be a big deal
  336.      * since this is an early allocation into the local heap.
  337.      * But it should be watched if the number of strings becomes
  338.      * large.
  339.      */
  340.     hMem=LocalAlloc(LPTR, COLESTRINGS*CCHOLESTRINGMAX);
  341.  
  342.     if (hMem==NULL)
  343.         return (HANDLE)NULL;
  344.  
  345.     /*
  346.      * This operation is only valid for FIXED memory.  Otherwise use
  347.      * LocalLock.
  348.      */
  349.     pch=(char *)hMem;
  350.  
  351.  
  352.     /*
  353.      * Load the strings into the memory and retain the specific
  354.      * pointer to that string.
  355.      */
  356.     for (i=IDS_OLEFIRST; i < IDS_OLELAST; i++)
  357.         {
  358.         cch=LoadString(hInst, i, (LPSTR)(pch+cchUsed), CCHOLESTRINGMAX-1);
  359.         PSZOLE(i)=(char *)(pch+cchUsed);
  360.  
  361.         /*
  362.          * One is added to cch to include a NULL.  The memory was ZEROINITed
  363.          * on allocation so by skipping a byte we get the NULL.
  364.          */
  365.         cchUsed +=cch+1;
  366.         }
  367.  
  368.     /*
  369.      * We are assuming that no string is over CCHSTRINGMAX, and therefore
  370.      * we did not use all the allocated memory.  Therefore LocalReAlloc
  371.      * will only SHRINK the block, never expand it.  So if it fails, we
  372.      * don't care--all the strings are still there, we just wasted some
  373.      * space.
  374.      */
  375.     LocalReAlloc(hMem, cchUsed+1, LPTR);
  376.  
  377.     return hMem;
  378.     }
  379.